package com.qfjy.common.util.redis;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * todo Redis 解决高并发(重复提交)  幂等性
 */
@Service
@Slf4j
public class RepeatUtil {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 正常时间
     */
    private static long TOKEN_TIMEOUT_MINUTE = 30;

    public void generatorToken(HttpServletRequest request, String key) {
        /**
         * 1.生成 redis key命名建议: repeat:请求路径 +uuid
         * 2.存入Redis string,添加并设置过期时间
         * 3.存放到request作用域
         */
        String uuid = UUID.randomUUID().toString();
        key += uuid;

//        redisTemplate.opsForValue().set(key, uuid);
        redisTemplate.opsForValue().set(key, uuid, TOKEN_TIMEOUT_MINUTE, TimeUnit.MINUTES);
        request.setAttribute("token", uuid);
    }

    public void generatorToken(HttpServletRequest request, String key,Integer time) {
        /**
         * 1.生成 redis key命名建议: repeat:请求路径 +uuid
         * 2.存入Redis string,添加并设置过期时间
         * 3.存放到request作用域
         */
        String uuid = UUID.randomUUID().toString();
        key += uuid;

//        redisTemplate.opsForValue().set(key, uuid);
        redisTemplate.opsForValue().set(key, uuid, time, TimeUnit.MINUTES);
        request.setAttribute("token", uuid);
    }

    /**
     * todo 校验 Redis token
     */
    public boolean validateToken(HttpServletRequest request, String key) {
        /**
         * 校验 token (判断此次请求是否是重复提交)
         * 1.得到前端 token值
             * 2.得到 Redis值,查询 redisKey对应的 value,立即删除 Redis数据
         * 对前端的值和 Redis的值进行比较(如果相等,执行业务逻辑;如果不相等,叛党重复提交)
         *
         */
        String token = request.getParameter("token");
        String redisKey = key + token;
        String redisKeyValue = (String) redisTemplate.opsForValue().get(redisKey);

        redisTemplate.delete(redisKey);
        if (token.equals(redisKeyValue)) {
            // 相等,redisKeyValue不是null,证明是第一次访问,应该添加
            return true;
        }


        // 第一次进来的时候,比对过后把redis中的redisKey删除了,
        // 第二次进来的后获得的redisKeyValue为null
        // 所以不相等的时候就是非第一次进来
        return false;

    }


}
